from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time
import base64
import ddddocr
import traceback
import os


def simple_auto_login():
    """
    简化版的自动登录函数，不依赖PIL的ANTIALIAS属性
    使用直接的方式获取验证码并处理登录
    """
    # 设置Chrome选项，优化自动化
    options = webdriver.ChromeOptions()
    options.add_argument('--disable-blink-features=AutomationControlled')
    options.add_argument('--start-maximized')
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)

    # 创建driver并访问登录页面
    driver = webdriver.Chrome(options=options)
    driver.execute_cdp_cmd('Network.setUserAgentOverride', {
        "userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
    })

    # 导航到登录页面
    print("访问登录页面...")
    login_url = "https://www.i-elitech.net/user/login"
    driver.get(login_url)

    try:
        # 等待登录表单加载
        WebDriverWait(driver, 15).until(
            EC.visibility_of_element_located((By.ID, "userName"))
        )

        # 用户凭据
        username = "temp_d121"
        password = "D121d121d121@"

        # 填写表单
        print("填写登录表单...")
        driver.find_element(By.ID, "userName").send_keys(username)
        driver.find_element(By.ID, "accountPassword").send_keys(password)

        # 获取验证码图片 - 直接使用base64方法，不涉及PIL
        try:
            print("获取验证码...")
            captcha_img = driver.find_element(By.CSS_SELECTOR, "img.verify-code")

            # 直接从img元素获取base64数据
            img_src = captcha_img.get_attribute('src')
            if img_src.startswith('data:image'):
                base64_data = img_src.split(',')[1]
                captcha_bytes = base64.b64decode(base64_data)

                # 使用ddddocr识别验证码
                ocr = ddddocr.DdddOcr()
                captcha_text = ocr.classification(captcha_bytes)
                print(f"识别出的验证码: {captcha_text}")

                # 填写验证码
                driver.find_element(By.ID, "verCode").send_keys(captcha_text)
            else:
                print("无法获取验证码图片，将使用JavaScript")
                # 备用方法：使用JavaScript获取图像数据
                captcha_base64 = driver.execute_script("""
                    var canvas = document.createElement('canvas');
                    var ctx = canvas.getContext('2d');
                    var img = arguments[0];
                    canvas.height = img.naturalHeight;
                    canvas.width = img.naturalWidth;
                    ctx.drawImage(img, 0, 0);
                    return canvas.toDataURL('image/png').substring(22);
                """, captcha_img)

                captcha_bytes = base64.b64decode(captcha_base64)
                ocr = ddddocr.DdddOcr()
                captcha_text = ocr.classification(captcha_bytes)
                print(f"JS方法识别的验证码: {captcha_text}")

                driver.find_element(By.ID, "verCode").send_keys(captcha_text)

        except Exception as e:
            print(f"验证码处理异常: {e}")
            traceback.print_exc()
            # 如果无法处理验证码，我们会继续并尝试登录

        # 勾选同意协议
        agree_checkbox = driver.find_element(By.ID, "agree")
        if not agree_checkbox.is_selected():
            driver.execute_script("arguments[0].click();", agree_checkbox)

        # 点击登录按钮
        print("点击登录按钮...")
        driver.execute_script("""
            var buttons = document.querySelectorAll('button');
            for(var i=0; i<buttons.length; i++) {
                if(buttons[i].textContent.includes('登录')) {
                    buttons[i].click();
                    return true;
                }
            }
            // 尝试提交表单
            document.querySelector('form').submit();
        """)

        # 等待登录处理
        print("等待登录处理...")
        time.sleep(5)

        # 使用 JavaScript 检查和处理可能的 data: URL
        current_url = driver.execute_script("return window.location.href")
        print(f"登录后URL: {current_url}")

        # 检查是否需要导航到主页
        if current_url.startswith("data:") or "home" not in current_url:
            print(f"需要导航到主页，当前URL: {current_url}")
            # 尝试直接通过JavaScript打开主页，避免Selenium的get方法
            driver.execute_script("window.location.href = 'https://www.i-elitech.net/home';")
            print("已使用JavaScript导航到主页")
            time.sleep(10)  # 等待页面加载

        # 再次检查URL
        current_url = driver.execute_script("return window.location.href")
        print(f"导航后URL: {current_url}")

        # 如果仍不在主页
        if current_url.startswith("data:") or "home" not in current_url:
            print("仍然不在主页，尝试使用Selenium的get方法")
            driver.get("https://www.i-elitech.net/home")
            time.sleep(10)  # 等待页面加载

        return driver
    except Exception as e:
        print(f"登录过程中发生异常: {e}")
        traceback.print_exc()
        return driver


def execute_home_sequence(driver):
    """
    使用集成方法一次性完成主页上的操作序列:
    1. 点击"在线设备"
    2. 点击"1030"设备
    3. 点击"数据图表"标签
    """
    if driver is None:
        print("无效的driver对象")
        return False

    try:
        # 检查当前URL
        current_url = driver.execute_script("return window.location.href")
        print(f"执行操作前URL: {current_url}")

        # 确保在主页上
        if "login" in current_url:
            print("当前在登录页面，登录可能已失败")
            return False

        if current_url.startswith("data:") or "home" not in current_url:
            print(f"不在主页，尝试导航到主页")
            driver.get("https://www.i-elitech.net/home")
            time.sleep(10)

        # 使用强大的JavaScript全链路处理，尝试完成整个流程
        print("开始执行JavaScript完成整个操作流程...")

        # 1. 查找页面上的所有文本和元素，帮助调试
        all_text = driver.execute_script("""
            var allText = document.body.innerText;
            return allText;
        """)

        # 检查页面是否包含预期内容
        if "在线设备" in all_text:
            print("页面包含'在线设备'文本")
        else:
            print("警告: 页面不包含'在线设备'文本")

        # 全链路JavaScript操作序列
        success = driver.execute_script("""
            // 辅助函数：模拟真实点击
            function simulateRealClick(element) {
                if (!element) return false;

                try {
                    // 高亮元素
                    element.style.border = '3px solid red';
                    element.scrollIntoView({behavior: 'smooth', block: 'center'});

                    // 短暂延迟
                    let now = new Date().getTime();
                    let endTime = now + 500;
                    while(new Date().getTime() < endTime);

                    // 模拟事件序列
                    const rect = element.getBoundingClientRect();
                    const centerX = rect.left + rect.width / 2;
                    const centerY = rect.top + rect.height / 2;

                    const events = ['mouseover', 'mousedown', 'mouseup', 'click'];
                    events.forEach(eventType => {
                        const event = new MouseEvent(eventType, {
                            bubbles: true,
                            cancelable: true,
                            view: window,
                            clientX: centerX,
                            clientY: centerY
                        });
                        element.dispatchEvent(event);
                    });

                    return true;
                } catch (e) {
                    console.error('点击失败:', e);
                    return false;
                }
            }

            // 辅助函数：等待时间
            function sleep(ms) {
                return new Promise(resolve => setTimeout(resolve, ms));
            }

            // 辅助函数：等待元素出现
            async function waitForElement(selector, text, timeoutMs) {
                const startTime = new Date().getTime();

                while (new Date().getTime() - startTime < timeoutMs) {
                    let elements;
                    if (selector) {
                        elements = document.querySelectorAll(selector);
                    } else {
                        elements = Array.from(document.querySelectorAll('*')).filter(e => 
                            e.textContent && e.textContent.includes(text));
                    }

                    if (elements && elements.length > 0) {
                        return elements;
                    }

                    // 等待100ms再检查
                    await sleep(100);
                }

                return null;
            }

            // 主操作序列
            async function executeSequence() {
                try {
                    // 1. 点击"在线设备"
                    console.log('寻找在线设备元素...');

                    // 尝试多种选择器
                    let deviceBox = null;

                    // 方法1: 查找特定类名的box元素
                    const boxes = document.querySelectorAll('div.box');
                    for (let box of boxes) {
                        if (box.textContent.includes('在线设备')) {
                            deviceBox = box;
                            break;
                        }
                    }

                    // 方法2: 查找包含特定文本的p.title元素
                    if (!deviceBox) {
                        const titles = document.querySelectorAll('p.title');
                        for (let title of titles) {
                            if (title.textContent.trim() === '在线设备') {
                                // 找到标题的父盒子
                                deviceBox = title.closest('div.box') || title.parentElement;
                                break;
                            }
                        }
                    }

                    // 方法3: 查找任何包含在线设备文本的元素
                    if (!deviceBox) {
                        const elements = Array.from(document.querySelectorAll('*')).filter(e => 
                            e.textContent && e.textContent.trim() === '在线设备');

                        if (elements.length > 0) {
                            // 找到可点击的父元素
                            let el = elements[0];
                            while (el && !['DIV', 'A', 'BUTTON', 'LI'].includes(el.tagName)) {
                                el = el.parentElement;
                            }
                            deviceBox = el || elements[0];
                        }
                    }

                    if (deviceBox) {
                        console.log('找到在线设备元素:', deviceBox);
                        if (!simulateRealClick(deviceBox)) {
                            console.log('点击在线设备失败');
                            return false;
                        }
                        console.log('已点击在线设备');
                    } else {
                        console.log('未找到在线设备元素');
                        return false;
                    }

                    // 等待设备列表加载
                    await sleep(5000);

                    // 2. 点击"1030"设备
                    console.log('寻找1030设备...');

                    // 等待设备元素出现
                    const deviceElements = await waitForElement('span.device-name', '1030', 10000);
                    let deviceElement = null;

                    if (deviceElements) {
                        for (let element of deviceElements) {
                            if (element.textContent.includes('1030')) {
                                deviceElement = element;
                                break;
                            }
                        }
                    }

                    // 如果没找到，尝试其他选择器
                    if (!deviceElement) {
                        const allElements = Array.from(document.querySelectorAll('*')).filter(e => 
                            e.textContent && e.textContent.includes('1030'));

                        if (allElements.length > 0) {
                            deviceElement = allElements[0];
                        }
                    }

                    if (deviceElement) {
                        console.log('找到1030设备:', deviceElement);
                        // 找到可点击的父元素
                        let clickTarget = deviceElement;
                        while (clickTarget && !['DIV', 'A', 'BUTTON', 'P', 'LI', 'SPAN'].includes(clickTarget.tagName)) {
                            clickTarget = clickTarget.parentElement;
                        }

                        // 如果没有合适的父元素，使用原始元素
                        if (!clickTarget) clickTarget = deviceElement;

                        if (!simulateRealClick(clickTarget)) {
                            console.log('点击1030设备失败');
                            return false;
                        }
                        console.log('已点击1030设备');
                    } else {
                        console.log('未找到1030设备元素');
                        return false;
                    }

                    // 等待设备详情加载
                    await sleep(5000);

                    // 3. 点击"数据图表"标签
                    console.log('寻找数据图表标签...');

                    // 等待标签元素出现
                    const tabElements = await waitForElement('div[role="tab"]', '数据图表', 10000);
                    let dataChartTab = null;

                    if (tabElements) {
                        for (let tab of tabElements) {
                            if (tab.textContent.trim() === '数据图表') {
                                dataChartTab = tab;
                                break;
                            }
                        }
                    }

                    // 如果没找到，尝试其他选择器
                    if (!dataChartTab) {
                        const allElements = Array.from(document.querySelectorAll('*')).filter(e => 
                            e.textContent && e.textContent.trim() === '数据图表');

                        if (allElements.length > 0) {
                            dataChartTab = allElements[0];
                        }
                    }

                    if (dataChartTab) {
                        console.log('找到数据图表标签:', dataChartTab);
                        if (!simulateRealClick(dataChartTab)) {
                            console.log('点击数据图表标签失败');
                            return false;
                        }
                        console.log('已点击数据图表标签');
                    } else {
                        console.log('未找到数据图表标签');
                        return false;
                    }

                    console.log('操作序列执行完成');
                    return true;

                } catch (error) {
                    console.error('执行中发生错误:', error);
                    return false;
                }
            }

            // 执行操作序列并返回结果
            return executeSequence();
        """)

        if success:
            print("操作序列执行成功")
            return True
        else:
            print("操作序列执行失败")
            return False

    except Exception as e:
        print(f"执行操作序列时发生异常: {e}")
        traceback.print_exc()
        return False


# 主程序
if __name__ == "__main__":
    print("\n===== 启动自动化程序 =====")
    print(f"当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")

    # 登录
    print("\n----- 开始登录流程 -----")
    driver = simple_auto_login()

    if driver:
        try:
            # 执行主页操作序列
            print("\n----- 开始执行主页操作 -----")
            success = execute_home_sequence(driver)

            if success:
                print("\n✓ 所有操作已成功完成")
            else:
                print("\n✗ 操作序列执行未完成")

            # 保持浏览器打开
            print("\n浏览器将保持打开状态")
            print("按Ctrl+C可终止程序")

            # 手动尝试访问主页（如果前面的尝试都失败了）
            try:
                current_url = driver.current_url
                if current_url.startswith("data:") or "/home" not in current_url:
                    print("\n尝试再次访问主页...")
                    driver.get("https://www.i-elitech.net/home")
                    print("已导航到主页。如果您看到页面已加载，请尝试手动点击'在线设备'按钮")
            except:
                pass

            while True:
                time.sleep(60)
        except KeyboardInterrupt:
            print("程序被用户终止")
        except Exception as e:
            print(f"程序执行中发生未预期的错误: {e}")
            traceback.print_exc()

        print("\n程序结束")
    else:
        print("登录失败，无法继续操作")